package cn.edu.zufe.mjt.nio;

import cn.edu.zufe.mjt.constans.InternetAddressConstants;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;

/**
 * @author 蒙锦涛
 * @date 2025/6/26
 */


public class NioServer {
	public static void main(String[] args) throws IOException {
		// ServerSocketChannel 类比大马路， SocketChannel 类比小马路，Buffer 在小马路上传输，可以看做车辆或者行人；Selector 是一个监听器
		Selector selector = Selector.open();
		ServerSocketChannel ssc = ServerSocketChannel.open();
		ssc.configureBlocking(false);
		ssc.bind(new InetSocketAddress(InternetAddressConstants.HOST, InternetAddressConstants.PORT));
		// ServerSocketChannel 只能有一个事件，就是 ACCEPT，因为 Channel 没有读写能力
		ssc.register(selector, SelectionKey.OP_ACCEPT);

		while (true) {
			selector.select(); // 在大马路上监听
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			while (iterator.hasNext()) {
				SelectionKey key = iterator.next();
				iterator.remove(); // 移除
				if (key.isAcceptable()) {
					ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
					SocketChannel client = serverSocketChannel.accept(); // 获取大马路里的小马路，也就是一个客户端
					client.configureBlocking(false);
					client.register(selector, SelectionKey.OP_READ);
					System.out.println(client.getRemoteAddress() + " 连接了");
				}
				if (key.isReadable()) { // 如果是可读的，说明获取到的事 SocketChannel，因为 ServerSocketChannel 只有Accept事件，并不能读取
					SocketChannel channel = (SocketChannel) key.channel();
					ByteBuffer buffer = ByteBuffer.allocate(1024);
					int length = channel.read(buffer);
					if (length == -1) {
						System.out.println("客户端断开连接" + channel.getRemoteAddress());
						channel.close();
					} else {
						buffer.flip();
						byte[] bytes = new byte[buffer.remaining()];
						buffer.get(bytes);
						String message = new String(bytes, StandardCharsets.UTF_8);
						System.out.println("客户端发送的消息: " + message);
					}
				}
			}
		}

	}
}
